package com.dhcc.bpm.modules.metadata.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.exception.BusinessException;
import com.dhcc.bpm.common.utils.ExcelUtil;
import com.dhcc.bpm.modules.common.entity.Upload;
import com.dhcc.bpm.modules.common.service.IPluploadService;
import com.dhcc.bpm.modules.metadata.entity.Metadata;
import com.dhcc.bpm.modules.metadata.entity.StrucMeta;
import com.dhcc.bpm.modules.metadata.mapper.StrucMetaMapper;
import com.dhcc.bpm.modules.metadata.service.IMetadataService;
import com.dhcc.bpm.modules.metadata.service.IStrucMetaService;
import com.dhcc.bpm.modules.metadata.vo.MetadataVO;
import com.dhcc.bpm.modules.metadata.vo.StrucMetaVO;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * @ClassName MetadataController
 * @Description 元数据表 控制器
 * @Author daina
 * @Date 2020/2/21 14:16
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@RestController
@AllArgsConstructor
@RequestMapping("bpm-metadata/metadata")
@Api(value = "元数据表", tags = "元数据表接口")
public class MetadataController extends BladeController {
    private static final Logger log = LoggerFactory.getLogger(MetadataController.class);
    private IMetadataService metadataService;
    @Autowired
    private IPluploadService pluploadService;
    private IStrucMetaService strucMetaService;
    private ISerialNumberService serialNumberService;
    private StrucMetaMapper strucMetaMapper;

    /**
     * @param metadata
     * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.metadata.vo.MetadataVO>
     * @Description 详情
     * @Author daina
     * @Date 10:43 2020/2/22
     **/
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "详情", notes = "传入metadata")
    @ApiLog("详情")
    @Log(title = "查询", businessType = BusinessType.SELECT)
    public R<MetadataVO> detail(MetadataVO metadata) {
        MetadataVO detail = metadataService.selectDetailInfo(metadata);
        return R.data(detail);
    }

    /**
     * @param metadata
     * @return org.springblade.core.tool.api.R<java.util.List < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 分页 元数据表
     * @Author daina
     * @Date 10:43 2020/2/22
     **/
    @GetMapping("/list")
    @ApiOperationSupport(order = 2)
    @ApiLog("分页 元数据表")
    @ApiOperation(value = "分页", notes = "传入metadata")
    @Log(title = "分页 元数据表", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> list(@ApiIgnore @RequestParam Map<String, Object> metadata, Query query) {
//        IPage<MetadataVO> pages = metadataService.page(Condition.getPage(query), Condition.getQueryWrapper(metadata, MetadataVO.class));
        IPage<MetadataVO> pages = metadataService.selectMetadataList(Condition.getPage(query), metadata);
//        MetadataWrapper.build().listNodeVOs(list);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 元数据表
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("自定义分页")
    @Log(title = "自定义分页", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> page(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectMetadataPage(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 查询选中的复合结构体元数据
     * @Author daina
     * @Date 10:44 2021/4/29
     **/
    @GetMapping("/structMetalist")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("自定义分页")
    @Log(title = "自定义分页", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> structMetalist(MetadataVO metadata, Query query) {
        if (null != metadata.getIds() && !"".equals(metadata.getIds())) {
            metadata.setMetaIds(Func.toLongList(metadata.getIds()));
            IPage<MetadataVO> pages = metadataService.structMetalist(Condition.getPage(query), metadata);
            return R.data(pages);
        } else {
            return R.data(null);
        }
    }

    /**
     * @param metadata
     * @param response
     * @return void
     * @Description 元数据导出
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @PostMapping("/listMetadataToExcel")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("导出文件")
    @Log(title = "导出文件", businessType = BusinessType.EXPORT)
    public void listMetadataToExcel(Metadata metadata, HttpServletResponse response) {
        List<Metadata> metadataLists = metadataService.listMetadataToExcel(metadata);
        ExcelUtil<Metadata> util = new ExcelUtil<Metadata>(Metadata.class);
        util.exportExcel(metadataLists, "元数据信息表", response);
    }

    /**
     * @param request
     * @return org.springblade.core.tool.api.R<java.lang.Boolean>
     * @Description 元数据导入
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @PostMapping("/import")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("文件导入")
    @Log(title = "文件导入", businessType = BusinessType.IMPORT)
    public R<Boolean> excelToMetadata(HttpServletRequest request) throws Exception {
        Upload upload = new Upload();
        upload.setRequest(request);
        Upload uploadEntity = pluploadService.getFile(upload);
        MultipartFile multipartFile = uploadEntity.getMultipartFile();
        ExcelUtil<Metadata> util = new ExcelUtil<>(Metadata.class);
        List<Metadata> metadataLists = util.importExcel(multipartFile.getInputStream());

        for (int i = 0; i < metadataLists.size(); i++) {
            Metadata item = metadataLists.get(i);
            //从excel看 表头也占一行
            if (null == item.getFieldName() || "".equals(item.getFieldName())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【元数据名称】" + "为空");
            } else if (null == item.getFieldCode() || "".equals(item.getFieldCode())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【元数据编码】" + "为空");
            } else if (null == item.getElementType() || "".equals(item.getElementType())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【元素类型】" + "为空");
            } else if (null == item.getXmlWrapped() || "".equals(item.getXmlWrapped())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【xmlWrapped】" + "为空");
            } else if (null == item.getElementGroupType() || "".equals(item.getElementGroupType())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【元素标准分组】" + "为空");
            } else if (null == item.getSensData() || "".equals(item.getSensData())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【是否敏感数据】" + "为空");
            } else if ("1".equals(item.getSensData()) && (null == item.getSensType() || "".equals(item.getSensType()))) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【脱敏方式】" + "为空");
            } else if (null == item.getFieldType() || "".equals(item.getFieldType())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【元数据类型】" + "为空");
            } else if (null == item.getIsRequired() || "".equals(item.getIsRequired())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【是否必填】" + "为空");
            } else if (null == item.getFieldLength() || "".equals(item.getFieldLength())) {
                return R.fail(222, "导入元数据失败,第" + (i + 2) + "行的【长度】" + "为空");
            }
        }
        Boolean flag = false;
        if (metadataLists != null && metadataLists.size() != 0) {
            try {
                flag = metadataService.saveBatch(metadataLists);
            } catch (Exception e) {
                log.error("导入元数据失败：{}", e);
                if (e.getMessage().contains("ORA-00001")) {
                    return R.fail(222, "违反唯一约束条件,请检查修改文件数据内容！");
                }
                return R.fail(222, "导入元数据失败");
            }
//            for (Metadata metadata:metadataLists){
//                flag = metadataService.save(metadata);
//            }
        } else {
            return R.fail(222, "导入数据不能为空！");
        }
        return R.data(flag);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 网关参数元数据表
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @GetMapping("/selectGateMetadataList")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("自定义分页 网关参数元数据表")
    @Log(title = "查询", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> selectGateMetadataList(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectGateMetadataList(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 网关校验参数元数据表
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @GetMapping("/selectGateParamCheckList")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("查询网关校验参数元数据表")
    @Log(title = "查询网关校验参数元数据表", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> selectGateParamCheckList(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectGateParamCheckList(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 查询源数据列表
     * @Author daina
     * @Date 10:44 2020/2/22
     **/
    @GetMapping("/selectNotInGateParamCheckList")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("查询源数据列表")
    @Log(title = "查询源数据列表", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> selectNotInGateParamCheckList(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectNotInGateParamCheckList(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 请求参数
     * @Author daina
     * @Date 10:45 2020/2/22
     **/
    @GetMapping("/selectReqMetadataList")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("查询请求参数")
    @Log(title = "查询请求参数", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> selectReqMetadataList(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectReqMetadataList(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 响应参数
     * @Author daina
     * @Date 10:45 2020/2/22
     **/
    @GetMapping("/selectResMetadataList")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("查询响应参数")
    @Log(title = "查询响应参数", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> selectResMetadataList(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.selectResMetadataList(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 请求参数添加元数据
     * @Author daina
     * @Date 10:45 2020/2/22
     **/
    @GetMapping("/listUnSelectReqMetadata")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("请求参数添加元数据")
    @Log(title = "请求参数添加元数据", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> listUnSelectReqMetadata(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.listUnSelectReqMetadata(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 复合结构体添加元数据
     * @Author daina
     * @Date 10:45 2021/4/29
     **/
    @GetMapping("/listUnSelectStructMeta")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("复合结构体添加元数据")
    @Log(title = "复合结构体添加元数据", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> listUnSelectStructMeta(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.listUnSelectStructMeta(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 自定义分页 响应参数添加元数据
     * @Author daina
     * @Date 10:45 2020/2/22
     **/
    @GetMapping("/listUnSelectResMetadata")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("响应参数添加元数据")
    @Log(title = "响应参数添加元数据", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> listUnSelectResMetadata(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.listUnSelectResMetadata(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 分页 网关公共参数添加元数据
     * @Author daina
     * @Date 10:45 2020/2/22
     **/
    @GetMapping("/listUnSelectCommonMetadata")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入metadata")
    @ApiLog("网关公共参数添加元数据")
    @Log(title = "网关公共参数添加元数据", businessType = BusinessType.SELECT)
    public R<IPage<MetadataVO>> listUnSelectCommonMetadata(MetadataVO metadata, Query query) {
        IPage<MetadataVO> pages = metadataService.listUnSelectCommonMetadata(Condition.getPage(query), metadata);
        return R.data(pages);
    }

    /**
     * @param metadata
     * @return org.springblade.core.tool.api.R
     * @Description 新增 元数据表
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @ApiLog("新增元数据")
    @ApiOperation(value = "新增", notes = "传入metadata")
    @Log(title = "新增元数据", businessType = BusinessType.INSERT)
    public R save(@Valid @RequestBody Metadata metadata) {
        return R.status(metadataService.save(metadata));
    }

    /**
     * @param metadata
     * @return org.springblade.core.tool.api.R
     * @Description 修改 元数据表
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @ApiLog(" 修改 元数据表")
    @ApiOperation(value = "修改", notes = "传入metadata")
    @Log(title = " 修改 元数据表", businessType = BusinessType.UPDATE)
    public R update(@Valid @RequestBody Metadata metadata) {
        return R.status(metadataService.updateById(metadata));
    }

    /**
     * @param metadata
     * @return org.springblade.core.tool.api.R
     * @Description 新增或修改 元数据表
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiLog("新增")
    @ApiOperation(value = "新增或修改", notes = "传入metadata")
    @Log(title = "新增", businessType = BusinessType.INSERT)
    public R submit(@Valid @RequestBody MetadataVO metadata) {


        if (null == metadata.getParentId()) {
            //父节点
            metadata.setParentId(0L);
        }
        //  数据类型 1=String,2=Integer,3=Double,4=Long,5=Enum,6=Char,7=Byte,8=Boolean
        if (!"5".equals(metadata.getFieldType())) {
            //不是枚举类型
            metadata.setFieldEnum("");
        }
        String id = "";
        Metadata meta = new Metadata();
        BeanUtils.copyProperties(metadata, meta);
        Boolean bool = true;
        if (null != metadata.getId() && !"".equals(metadata.getId())) {
            bool = metadataService.saveOrUpdate(meta);
        } else {
            id = serialNumberService.generateSerialNumberByModelCode("opc_issue_api");
            meta.setId(Long.valueOf(id));
            bool = metadataService.save(meta);
        }
        StrucMetaVO strucMetavo = new StrucMetaVO();
        strucMetavo.setStructureId(meta.getId());
        List<StrucMetaVO> voLists = strucMetaMapper.listRelateData(strucMetavo);
        if (voLists.size() > 0) {
            for (StrucMetaVO sm : voLists) {
                strucMetaService.removeById(sm.getId());
            }
        }
        if ("3".equals(metadata.getElementType())) {
            List<Long> list = Func.toLongList(metadata.getIds());
            for (Long metaid : list) {
                StrucMeta strucMeta = new StrucMeta();
                strucMeta.setStructureId(meta.getId());
                strucMeta.setMetadataId(metaid);
                bool = strucMetaService.save(strucMeta);
            }
        }
        return R.status(bool);
    }


    /**
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 删除 元数据表
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiLog("删除 元数据表")
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    @Log(title = "删除 元数据表", businessType = BusinessType.DELETE)
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(metadataService.deleteLogic(Func.toLongList(ids)));
    }

    /**
     * @param
     * @return org.springblade.core.tool.api.R<java.util.List < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 获取元数据树
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @GetMapping("/tree")
    @ApiLog("获取元数据树")
    @Log(title = "获取元数据树", businessType = BusinessType.SELECT)
    public R<List<MetadataVO>> tree() {
        List<MetadataVO> tree = metadataService.tree();
        return R.data(tree);
    }

    /**
     * @param metadata
     * @param bladeUser
     * @return org.springblade.core.tool.api.R<java.util.List < com.dhcc.bpm.modules.metadata.entity.Metadata>>
     * @Description 下拉产品
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @GetMapping("/select")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "下拉元数据名称", notes = "传入Metadata")
    @ApiLog("下拉产品")
    @Log(title = "下拉产品", businessType = BusinessType.SELECT)
    public R<List<Metadata>> select(Metadata metadata, BladeUser bladeUser) {
        QueryWrapper<Metadata> queryWrapper = Condition.getQueryWrapper(metadata);
        List<Metadata> list = metadataService.list((!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(Metadata::getTenantId, bladeUser.getTenantId()) : queryWrapper);
        return R.data(list);
    }

}
